#pragma once

#include <QObject>
#include <QHash>
#include <QList>
#include <QTimer>
#include <QDateTime>
#include <memory>
#include "auto_door.h"
#include "auto_door_protocol.h"
#include "infrastructure/io/tcp_socket_server.h"
#include "infrastructure/io/tcp_socket_client.h"
#include "kernel/interfaces/ILogger.h"

namespace application {
namespace auto_door {

/**
 * @brief 设备状态枚举
 */
enum class DeviceState {
    Offline,     // 离线
    Connecting,  // 正在连接（收到HELLO但未确认）
    Online       // 在线
};

/**
 * @brief 设备信息
 */
struct DeviceInfo {
    quint32 deviceId{0};               // 设备ID
    qint64 socketDescriptor{-1};       // TCP连接描述符
    infrastructure::io::TcpSocketClient* tcpClient{nullptr};  // TCP客户端
    AutoDoorProtocol* protocol{nullptr};  // 协议解析器
    QMetaObject::Connection readConnection; // readyRead 连接句柄
    DeviceState state{DeviceState::Offline};  // 设备状态
    QDateTime lastHeartbeat;           // 最后心跳时间
    uint16_t fwVersion{0};             // 固件版本
    uint8_t flags{0};                  // 能力标志
};

/**
 * @brief 自动门管理器
 * @details 管理自动门 TCP 服务，负责设备连接、协议通信与门控指令分发
 */
class AutoDoorManager : public QObject {
    Q_OBJECT

public:
    explicit AutoDoorManager(int floor, std::shared_ptr<kernel::ILogger> logger = nullptr, QObject* parent = nullptr);
    ~AutoDoorManager();

    // ========== TCP Server 管理 ==========

    /**
     * @brief 初始化TCP服务器
     * @param port 监听端口（默认9002）
     * @return 是否成功
     */
    bool initConnection(quint16 port = 9002);
    bool isServerRunning() const { return m_tcpServer != nullptr; }
    quint16 serverPort() const { return m_serverPort; }

    /**
     * @brief 停止TCP服务器
     */
    void stopConnection();

    // ========== 自动门管理 ==========

    /**
     * @brief 添加自动门配置
     * @param doorId 门ID
     * @param deviceId 硬件设备ID
     * @param point1 触发点1
     * @param point2 触发点2
     * @param openMask 开门LED掩码
     * @param closeMask 关门LED掩码
     */
    void addDoor(int doorId, quint32 deviceId, const QString& point1, const QString& point2,
                 quint8 openMask = 0x07, quint8 closeMask = 0x00, int floor = -1);

    /**
     * @brief 移除自动门
     */
    void removeDoor(int doorId);

    /**
     * @brief 获取自动门
     */
    std::shared_ptr<AutoDoor> getDoor(int doorId) const;

    /**
     * @brief 获取所有门ID
     */
    QList<int> getAllDoorIds() const;

    /**
     * @brief 根据点位查找门
     */
    std::shared_ptr<AutoDoor> findDoorByPoint(const QString& pointName) const;

    /**
     * @brief 根据连续站点查询门（支持双向）
     */
    std::shared_ptr<AutoDoor> findDoorBySegment(const QString& from, const QString& to) const;

    struct DoorInfo {
        int doorId{0};
        int floor{-1};
        quint32 deviceId{0};
        QString point1;
        QString point2;
        DoorState state{DoorState::Closed};
        bool deviceOnline{false};
    };

    QList<DoorInfo> getDoorInfos() const;

    // ========== 控制接口 ==========

    /**
     * @brief 打开指定门
     */
    void openDoor(int doorId);

    /**
     * @brief 关闭指定门
     */
    void closeDoor(int doorId);

    /**
     * @brief 获取楼层号
     */
    int getFloor() const { return m_floor; }

    // ========== 设备管理 ==========

    /**
     * @brief 获取设备在线状态
     */
    bool isDeviceOnline(quint32 deviceId) const;

    /**
     * @brief 获取所有在线设备
     */
    QList<quint32> getOnlineDevices() const;

signals:
    // 门相关信号
    void doorAdded(int doorId);
    void doorRemoved(int doorId);
    void doorStateChanged(int doorId, DoorState state);

    // 设备相关信号
    void deviceOnline(quint32 deviceId, uint16_t fwVersion);
    void deviceOffline(quint32 deviceId);

    // 控制结果信号
    void doorControlSuccess(int doorId, uint8_t levelMask);
    void doorControlFailed(int doorId, LedErrorCode errorCode);

private slots:
    // ========== TCP连接处理 ==========
    void onNewConnection(qint64 socketDescriptor, const QString& ip, quint16 port);
    void onClientDisconnected(qint64 socketDescriptor, const QString& ip, quint16 port);

    // ========== 协议消息处理 ==========
    void onHelloReceived(quint32 deviceId, uint16_t fwVersion, uint8_t flags, uint16_t sequence);
    void onHeartbeatReceived(quint32 deviceId, uint32_t uptime, uint16_t sequence);
    void onLedAckReceived(uint32_t programId, uint8_t levelMask, uint16_t sequence);
    void onLedErrorReceived(uint32_t programId, LedErrorCode errorCode, uint16_t sequence);
    void onProtocolError(const QString& error);

    // ========== 定时任务 ==========
    void checkDeviceTimeout();

private:
    // ========== 内部辅助方法 ==========

    /**
     * @brief 发送LED控制指令
     * @param deviceId 目标设备ID
     * @param programId 业务指令编号
     * @param levelMask LED掩码
     * @return 是否发送成功
     */
    bool sendLedControl(quint32 deviceId, uint32_t programId, uint8_t levelMask);

    /**
     * @brief 根据socket查找设备
     */
    DeviceInfo* findDeviceBySocket(qint64 socketDescriptor);

    /**
     * @brief 根据deviceId查找设备
     */
    DeviceInfo* findDeviceById(quint32 deviceId);

    /**
     * @brief 生成唯一的ProgramID
     */
    uint32_t generateProgramId();

    /**
     * @brief 构建站点对键
     */
    static QString buildPairKey(const QString& from, const QString& to);

    /**
     * @brief Start or reset the auto close timer for a door.
     */
    void startOrResetAutoCloseTimer(int doorId);

    /**
     * @brief Stop the auto close timer for a door.
     */
    void stopAutoCloseTimer(int doorId);

    /**
     * @brief Auto close timer callback.
     */
    void handleAutoCloseTimeout(int doorId);

private:
    QString floorTag() const;

    // ========== 基础信息 ==========
    int m_floor;
    std::shared_ptr<kernel::ILogger> m_logger;

    // ========== TCP Server ==========
    infrastructure::io::TcpSocketServer* m_tcpServer{nullptr};
    quint16 m_serverPort{9002};

    // ========== 自动门配置 ==========
    struct DoorConfig {
        int doorId{0};
        int floor{-1};
        quint32 deviceId{0};
        QString point1;
        QString point2;
        quint8 openMask{0x07};
        quint8 closeMask{0x00};
        std::shared_ptr<AutoDoor> doorObject;  // 门对象
    };

    QHash<int, DoorConfig> m_doorConfigs;         // doorId -> 门配置
    QHash<quint32, int> m_deviceToDoor;           // deviceId -> doorId
    QHash<QString, int> m_pointToDoor;            // 点位 -> doorId
    QHash<QString, int> m_segmentToDoor;          // 站点对 -> doorId

    // ========== 设备管理 ==========
    QHash<quint32, DeviceInfo> m_devices;         // deviceId -> 设备信息
    QHash<qint64, quint32> m_socketToDevice;      // socket -> deviceId
    QHash<uint32_t, int> m_programToDoor;         // programId -> doorId（追踪控制指令）

    // ========== 定时器 ==========
    QTimer* m_timeoutTimer{nullptr};              // 心跳超时检测定时器
    QHash<int, QTimer*> m_autoCloseTimers;        // doorId -> auto close timer
    static constexpr int AUTO_CLOSE_TIMEOUT_MS = 5000; // auto close timeout (ms)

    // ========== 计数器 ==========
    uint32_t m_programIdCounter{1};               // ProgramID计数器
    static constexpr int HEARTBEAT_TIMEOUT = 15;  // 心跳超时时间（秒）

    // ========== 连接跟踪 ==========
    QHash<qint64, DeviceInfo> m_pendingDevices;    // 尚未完成握手的连接
    QHash<AutoDoorProtocol*, qint64> m_protocolToSocket; // protocol -> socketDescriptor
};

} // namespace auto_door
} // namespace application
